package com.ftg.learn.chapter06;

import com.ftg.learn.chapter04.isa.Dog;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 学习一下线程
 *
 * @author 布衣
 */
public class LearnThread implements Runnable {

    // 生产者与消费者  (1)   小l
    // 一个厨师 一个消售人员  一个生产一个消费

    // 100张票  5个窗口同步锁售 小杰

    // 小苏 -- dfs  (小讲)


    Integer num = 0;

    /**
     * 同步锁  ：  synchronized   ：  表示当前LearnThread里面的所有实例，所有线程，当有一个线程占用  synchronized 修饰的test1方法
     * 那么其它线程就不用操作当前实例了
     * <p>
     * synchronized 放在方法声明上面，表示类锁
     * synchronized块  用来表示对变量上锁，锁定是一个代码块
     * <p>
     * 可重入锁   ： 锁的粒度越细，锁的竞争越小，性能越高  (锁的粒度越细，锁的竞争越小，性能越高)
     * Lock
     */

    private final Lock lock = new ReentrantLock();

    public void test1() {
        //上锁
        lock.lock();
        try {
            num++;
            System.out.println(Thread.currentThread().getName() + "==>" + num);
        } catch (Exception e) {

        } finally {
            lock.unlock();
        }
    }
//    public synchronized void test1() {
//        num++;
//    }

    @Override
    public void run() {
        for (int i = 0; i < 10000; i++) {
            test1();

        }
    }

    //线程 ：
    // 线程创建方式  ： 五种  ： 1. 继承 Thread 2. 实现 Runnable 3. 实现 Callable 4. 使用线程池 【2种方案】
    // 线程生命周期 ： 状态  新建 start();  就绪 (cpu时间片)  运行  （资源|cpu时间片） 阻塞(排队)  结束  run()完成了


    public static void main(String[] args) {
        LearnThread learnThread = new LearnThread();
//        learnThread.run();
//        System.out.println(learnThread.num);

        Thread t1 = new Thread(learnThread, "线程一");
        t1.start();
        Thread t2 = new Thread(learnThread, "线程二");
        t2.start();
        // 1 : 线程   ： 进程   ：
        // 2 ：线程五种状态 关系转换
        // 3 : start()  run();  sleep(); join();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        //同步程序
        System.out.println("===>" + learnThread.num);

//        //启动一个线程  使用run()  start();
//        Thread t = new Thread(new Runnable() {
//            @Override
//            public void run() {
//                System.out.println("我是线程T");
//            }
//        });
//        t.start();
//
//        Thread t1 = new Thread(() -> {
//            System.out.println("我是线程T1");
//        });
//        t1.start();

        //工作线程 :
        //守护线程 ： GC
        //主线程  ：  Main
    }

}
